package game

import (
	"bainiao/internal/db"
	"bainiao/internal/model"
	"errors"
	"github.com/gin-gonic/gin"
	"net/http"
	"time"
)

// 食材每小时补充量（示例配置）
var ingredientReplenish = map[string]int{
	"面粉": 2,
	"鸡蛋": 1,
	"牛奶": 1,
}

// Cook 处理烹饪请求（使用数据库配方）
func Cook(c *gin.Context) {
	var req struct {
		UserID   uint   `json:"user_id"`
		Recipe   string `json:"recipe"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 获取并更新游戏状态（含食材补充）
	state, err := getAndUpdateGameState(req.UserID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 从数据库获取菜谱信息
	recipe, err := getRecipeFromDB(req.Recipe)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusBadRequest, gin.H{"error": "未知菜谱"})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "获取菜谱失败"})
		}
		return
	}

	// 检查菜谱是否已解锁（根据店铺等级）
	if state.ShopLevel < recipe.UnlockedAt {
		c.JSON(http.StatusForbidden, gin.H{"error": "店铺等级不足，无法解锁该菜谱"})
		return
	}

	// 检查食材需求
	if !checkIngredientEnough(state.Ingredients, recipe.RequiredIngredients) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "食材不足"})
		return
	}

	// 消耗食材
	state.Ingredients = consumeIngredients(state.Ingredients, recipe.RequiredIngredients)
	// 增加菜品和金币（使用数据库配置的奖励）
	state.Dishes[req.Recipe]++
	state.Coins += recipe.RewardCoins
	// 自动解锁更高等级菜谱（示例：店铺等级+1时解锁新菜谱）
	if state.ShopLevel == recipe.UnlockedAt && state.Dishes[req.Recipe] >= 5 {
		state.ShopLevel++
		state.UnlockedRecipes = append(state.UnlockedRecipes, "超级蛋糕")
	}

	// 更新数据库状态
	if err := db.DB.Save(&state).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "状态保存失败"})
		return
	}

	// 更新用户任务进度
	updateUserTaskProgress(req.UserID, req.Recipe)

	// 转换为微信前端友好的展示格式
stateResp := gin.H{
	"ingredients": state.Ingredients,
	"coins": state.Coins,
	"shopLevel": state.ShopLevel,
	"unlockedRecipes": state.UnlockedRecipes,
	"lastLogin": time.Unix(state.LastLoginTime, 0).Format("2006-01-02 15:04:05"),
}
c.JSON(http.StatusOK, gin.H{"message": "烹饪成功", "state": stateResp})
}

// SaveArchive 保存游戏进度存档
func SaveArchive(c *gin.Context) {
	var req struct {
		UserID  uint   `json:"user_id"`
		Version string `json:"version"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 获取当前游戏状态
	state, err := getAndUpdateGameState(req.UserID)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	// 序列化状态为JSON
	stateJSON, err := json.Marshal(state)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "状态序列化失败"})
		return
	}

	// 创建存档记录
	archive := model.Archive{
		UserID:    req.UserID,
		StateJSON: string(stateJSON),
		Version:   req.Version,
		CreatedAt: time.Now().Unix(),
	}
	if err := db.DB.Create(&archive).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "存档保存失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "存档保存成功", "archive_id": archive.ID})
}

// LoadArchive 加载游戏进度存档
func LoadArchive(c *gin.Context) {
	var req struct {
		ArchiveID uint `json:"archive_id"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 查询存档记录
	var archive model.Archive
	if err := db.DB.First(&archive, req.ArchiveID).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "存档不存在"})
		return
	}

	// 反序列化状态
	var state model.GameState
	if err := json.Unmarshal([]byte(archive.StateJSON), &state); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "状态反序列化失败"})
		return
	}

	// 更新当前游戏状态
	if err := db.DB.Model(&model.GameState{}).Where("user_id = ?", state.UserID).Updates(state).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "状态加载失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "存档加载成功", "state": state})
}

// GetTransactionHistory 获取用户交易记录
func GetTransactionHistory(c *gin.Context) {
	var req struct {
		UserID   uint   `json:"user_id"`
		StartTS  int64  `json:"start_ts"` // 开始时间戳
		EndTS    int64  `json:"end_ts"`   // 结束时间戳
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	query := db.DB.Where("user_id = ?", req.UserID)
	if req.StartTS > 0 {
		query = query.Where("timestamp >= ?", req.StartTS)
	}
	if req.EndTS > 0 {
		query = query.Where("timestamp <= ?", req.EndTS)
	}

	var transactions []model.Transaction
	if err := query.Order("timestamp desc").Find(&transactions).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "查询交易记录失败"})
		return
	}

	// 计算总支出和总收入（收入来自任务奖励等）
	var totalCost, totalIncome int
	for _, t := range transactions {
		totalCost += t.TotalCost
	}
	// 查询任务奖励收入
	var userTasks []model.UserTask
	if err := db.DB.Where("user_id = ? AND completed = ?", req.UserID, true).Find(&userTasks).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "查询任务奖励失败"})
		return
	}
	for _, ut := range userTasks {
		var task model.Task
		if db.DB.Where("task_id = ?", ut.TaskID).First(&task).Error == nil {
			totalIncome += task.RewardCoins
		}
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "交易记录获取成功",
		"transactions": transactions,
		"total_cost": totalCost,
		"total_income": totalIncome,
		"net_profit": totalIncome - totalCost,
	})
}

// AutoReplenishCommodityStock 定时自动补充商品库存（需在服务启动时初始化）
func InitAutoReplenish() {
	// 每24小时执行一次
	interval := time.Hour * 24
	ticker := time.NewTicker(interval)

	go func() {
		for range ticker.C {
			// 查询需要自动补充的商品（假设商品表添加了ReplenishAmount字段）
			var commodities []model.Commodity
			if err := db.DB.Where("replenish_amount > 0").Find(&commodities).Error; err != nil {
				log.Printf("自动补充库存查询失败: %v", err)
				continue
			}

			for _, c := range commodities {
				// 补充库存（不超过最大库存限制）
				newStock := c.Stock + c.ReplenishAmount
				if c.MaxStock > 0 && newStock > c.MaxStock {
					newStock = c.MaxStock
				}
				if err := db.DB.Model(&c).Update("stock", newStock).Error; err != nil {
					log.Printf("商品 %s 库存补充失败: %v", c.Name, err)
				}
			}
			log.Println("完成商品库存自动补充")
		}
	}()
}

// getAndUpdateGameState 获取并更新游戏状态（含食材补充逻辑）
func getAndUpdateGameState(userID uint) (*model.GameState, error) {
	var state model.GameState
	if err := db.DB.Where("user_id = ?", userID).First(&state).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			// 初始化新用户游戏状态
			state = model.GameState{
				UserID:          userID,
				Ingredients:     map[string]int{"面粉": 10, "鸡蛋": 5, "牛奶": 8},
				Dishes:          make(map[string]int),
				UnlockedRecipes: []string{"基础蛋糕"},
				ShopLevel:       1,
				Coins:           100,
				LastLoginTime:   time.Now().Unix(),
			}
			return &state, db.DB.Create(&state).Error
			}
		return nil, err
	}

	// 计算上次登录至今的小时数
	now := time.Now().Unix()
	hours := (now - state.LastLoginTime) / 3600
	if hours > 0 {
		// 补充食材
		for name, amount := range ingredientReplenish {
			state.Ingredients[name] += amount * int(hours)
		}
		// 更新最后登录时间
		state.LastLoginTime = now
	}

	return &state, nil
}

// GetCommodityList 获取商品列表接口（适配微信前端展示）
func GetCommodityList(c *gin.Context) {
	var commodities []model.Commodity
	if err := db.DB.Find(&commodities).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error":"商品列表获取失败"})
		return
	}

	// 转换为前端友好格式（包含图片URL）
	var resp []gin.H
	for _, com := range commodities {
		resp = append(resp, gin.H{
			"id": com.ID,
			"name": com.Name,
			"type": com.Type,
			"price": com.CurrentPrice,
			"desc": com.Description,
			"stock": com.Stock,
			"image": com.ImageURL,
		})
	}

	c.JSON(http.StatusOK, gin.H{"message":"商品列表获取成功","list": resp})
}

// BuyCommodityHandler 处理商品购买请求
func BuyCommodityHandler(c *gin.Context) {
	var req struct {
		UserID     uint `json:"user_id"`
		CommodityID uint `json:"commodity_id"`
		Quantity   int `json:"quantity"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error":"参数错误"})
		return
	}

	// 验证数量有效性
	if req.Quantity <= 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error":"购买数量必须大于0"})
		return
	}

	// 查询用户游戏状态
	var userState model.GameState
	if err := db.DB.Where("user_id = ?", req.UserID).First(&userState).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error":"用户状态查询失败"})
		return
	}

	// 查询商品信息
	var commodity model.Commodity
	if err := db.DB.First(&commodity, req.CommodityID).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error":"商品不存在"})
		return
	}

	// 检查库存是否足够
	if commodity.Stock < req.Quantity {
		c.JSON(http.StatusBadRequest, gin.H{"error":"商品库存不足"})
		return
	}

	// 计算总金额
	totalPrice := commodity.CurrentPrice * req.Quantity
	if userState.Coins < totalPrice {
		c.JSON(http.StatusBadRequest, gin.H{"error":"金币不足"})
		return
	}

	// 扣除用户金币
	userState.Coins -= totalPrice
	if err := db.DB.Save(&userState).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error":"金币扣除失败"})
		return
	}

	// 减少商品库存
	commodity.Stock -= req.Quantity
	commodity.Last7DaysSales += req.Quantity // 更新最近7天销量
	if err := db.DB.Save(&commodity).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error":"库存更新失败"})
		return
	}

	// 创建交易记录
	transaction := model.Transaction{
		UserID:     req.UserID,
		CommodityID: req.CommodityID,
		Quantity:   req.Quantity,
		TotalPrice: totalPrice,
		CreateTime: time.Now().Unix(),
	}
	if err := db.DB.Create(&transaction).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error":"交易记录创建失败"})
		return
	}

	// 更新当日收益统计
	currentDate := time.Now().Format("2006-01-02")
	var revenue model.Revenue
	if err := db.DB.Where("date = ? AND source = ?", currentDate, "商品销售").First(&revenue).Error; err != nil {
		// 新日期初始化
		revenue = model.Revenue{
			Date:   currentDate,
			Total:  totalPrice,
			Source: "商品销售",
		}
	} else {
		revenue.Total += totalPrice
	}
	if err := db.DB.Save(&revenue).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error":"收益统计更新失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message":"购买成功","剩余金币":userState.Coins})
}

	// 查询商品信息
	var commodity model.Commodity
	if err := db.DB.First(&commodity, req.CommodityID).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "商品不存在"})
		return
	}

	// 检查库存
	if commodity.Stock < req.Amount {
		c.JSON(http.StatusBadRequest, gin.H{"error": "商品库存不足"})
		return
	}

	// 查询用户游戏状态
	var state model.GameState
	if err := db.DB.Where("user_id = ?", req.UserID).First(&state).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "用户状态不存在"})
		return
	}

	// 计算总费用
	totalCost := commodity.Price * req.Amount
	if state.Coins < totalCost {
		c.JSON(http.StatusBadRequest, gin.H{"error": "游戏货币不足"})
		return
	}

	// 扣除货币
	state.Coins -= totalCost
	// 更新背包
	state.Inventory[commodity.Name] += req.Amount
	// 减少商品库存
	commodity.Stock -= req.Amount
	// 创建交易记录
	transaction := model.Transaction{
		UserID:     req.UserID,
		CommodityID: req.CommodityID,
		Amount:     req.Amount,
		TotalCost:  totalCost,
		Timestamp:  time.Now().Unix(),
	}

	// 批量更新数据库
	if err := db.DB.Transaction(func(tx *gorm.DB) error {
		if err := tx.Save(&state).Error; err != nil {
			return err
		}
		if err := tx.Save(&commodity).Error; err != nil {
			return err
		}
		if err := tx.Create(&transaction).Error; err != nil {
			return err
		}
		return nil
	}); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "交易失败"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "购买成功", "inventory": state.Inventory})
}

// 辅助函数：从数据库获取菜谱信息
func getRecipeFromDB(recipeName string) (*model.Recipe, error) {
	var recipe model.Recipe
	if err := db.DB.Where("name = ?", recipeName).First(&recipe).Error; err != nil {
		return nil, err
	}
	return &recipe, nil
}

// 辅助函数：检查食材是否足够
func checkIngredientEnough(ingredients, cost map[string]int) bool {
	for name, need := range cost {
		if ingredients[name] < need {
			return false
		}
	}
	return true
}

// 辅助函数：消耗食材
func consumeIngredients(ingredients, cost map[string]int) map[string]int {
	newIngredients := make(map[string]int)
	for k, v := range ingredients {
		newIngredients[k] = v
	}
	for name, need := range cost {
		newIngredients[name] -= need
	}
	return newIngredients
}

// updateUserTaskProgress 更新用户任务进度
func updateUserTaskProgress(userID uint, recipe string) {
	// 查询用户未完成的任务
	var userTasks []model.UserTask
	if err := db.DB.Where("user_id = ? AND completed = ?", userID, false).Find(&userTasks).Error; err != nil {
		return
	}

	for _, ut := range userTasks {
		var task model.Task
		if err := db.DB.Where("task_id = ?", ut.TaskID).First(&task).Error; err != nil {
			continue
		}

		// 示例：任务类型为制作指定菜品
	if task.TargetType == "cook" && task.TargetValue == recipe {
			ut.Progress++
			if ut.Progress >= task.TargetValue {
				ut.Completed = true
				// 发放奖励
				var state model.GameState
				if db.DB.Where("user_id = ?", userID).First(&state).Error == nil {
					state.Coins += task.RewardCoins
					db.DB.Save(&state)
				}
			}
			db.DB.Save(&ut)
		}
	}
}

// Cook 处理烹饪请求
func Cook(c *gin.Context) {
	var req struct {
		UserID   string `json:"user_id"`
		Recipe   string `json:"recipe"`
	}
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 检查用户游戏状态是否存在
	state, exists := gameStates[req.UserID]
	if !exists {
		state = initGameState(req.UserID)
		gameStates[req.UserID] = state
	}

	// 检查菜谱是否已解锁
	if !contains(state.UnlockedRecipes, req.Recipe) {
		c.JSON(http.StatusForbidden, gin.H{"error": "该菜谱未解锁"})
		return
	}

	// 检查食材需求（示例菜谱：基础蛋糕需要2面粉+1鸡蛋+1牛奶）
	if req.Recipe == "基础蛋糕" {
		if state.Ingredients["面粉"] < 2 || state.Ingredients["鸡蛋"] < 1 || state.Ingredients["牛奶"] < 1 {
			c.JSON(http.StatusBadRequest, gin.H{"error": "食材不足"})
			return
		}
		// 消耗食材
		state.Ingredients["面粉"] -= 2
		state.Ingredients["鸡蛋"] -= 1
		state.Ingredients["牛奶"] -= 1
		// 增加菜品
		state.Dishes["基础蛋糕"]++
	}

	// 更新游戏状态
	gameStates[req.UserID] = state
	// 转换为微信前端友好的展示格式
stateResp := gin.H{
	"ingredients": state.Ingredients,
	"coins": state.Coins,
	"shopLevel": state.ShopLevel,
	"unlockedRecipes": state.UnlockedRecipes,
	"lastLogin": time.Unix(state.LastLoginTime, 0).Format("2006-01-02 15:04:05"),
}
c.JSON(http.StatusOK, gin.H{"message": "烹饪成功", "state": stateResp})
}

// GetGameStatus 获取当前游戏状态
func GetGameStatus(c *gin.Context) {
	userID := c.Query("user_id")
	state, exists := gameStates[userID]
	if !exists {
		c.JSON(http.StatusNotFound, gin.H{"error": "用户游戏状态未初始化"})
		return
	}
	c.JSON(http.StatusOK, state)
}

// contains 辅助函数检查切片是否包含元素
func contains(slice []string, item string) bool {
	for _, s := range slice {
		if s == item {
			return true
		}
	}
	return false
}